﻿using PmSoft.Core.Cryptos;
using System.ComponentModel.DataAnnotations;
using System.Text;

namespace Demo.PetaPoco.Application.Services.User;

/// <summary>
/// 用户密码辅助工具类
/// </summary>
public class UserPasswordHelper
{
	private static readonly Sm4CryptoUtility sm4CryptoUtility = new Sm4CryptoUtility();

	/// <summary>
	/// 检查用户密码是否正确
	/// </summary>
	/// <param name="password">用户录入的用户密码（尚未加密的密码）</param>
	/// <param name="storedPassword">数据库存储的密码（即加密过的密码）</param>
	/// <param name="passwordFormat">用户密码存储格式</param>
	public static bool CheckPassword(string password, string storedPassword, UserPasswordFormat passwordFormat)
	{
		string encodedPassword = EncodePassword(password, passwordFormat);

		return !string.IsNullOrEmpty(encodedPassword) && encodedPassword.Equals(storedPassword, StringComparison.OrdinalIgnoreCase);
	}

	/// <summary>
	/// 对用户密码进行编码
	/// </summary>
	/// <param name="password">需要加密的用户密码</param>
	/// <param name="passwordFormat">用户密码存储格式</param>
	public static string EncodePassword(string password, UserPasswordFormat passwordFormat)
	{
		return passwordFormat switch
		{
			UserPasswordFormat.MD5 => MD5Utility.Generate32BitMD5(password),
			UserPasswordFormat.SM3 => SM3Utility.Encrypt(password),
			UserPasswordFormat.SM4 => Encoding.UTF8.GetString(sm4CryptoUtility.EncryptCBC(password, "")),
			_ => password
		};
	}

	/// <summary>
	/// 对密码解密
	/// </summary>
	/// <param name="password"></param>
	/// <param name="passwordFormat"></param>
	/// <returns></returns>
	public static string DecodePassword(string password, UserPasswordFormat passwordFormat)
	{
		return passwordFormat == UserPasswordFormat.SM4
			? Encoding.UTF8.GetString(sm4CryptoUtility.DecryptCBC(password, ""))
			: password;
	}
}

/// <summary>
/// 用户密码存储格式
/// </summary>
public enum UserPasswordFormat
{
	/// <summary>
	/// 密码未加密
	/// </summary>
	[Display(Name = "不加密")]
	Clear = 0,

	/// <summary>
	/// 标准MD5加密
	/// </summary>
	[Display(Name = "MD5加密")]
	MD5 = 1,

	/// <summary>
	/// 国密三加密
	/// </summary>
	[Display(Name = "国密3加密")]
	SM3 = 2,

	/// <summary>
	/// 国密四加密
	/// </summary>
	[Display(Name = "国密4加密")]
	SM4 = 3
}
